﻿using System;

using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace HorrorsOfArkham.Game_Application_Layer
{
    public abstract class XnaGame
    {
        #region Members

        private readonly ContentManager _content;
        private readonly GraphicsDevice _graphicsDevice;

        public bool Running
        {
            get;
            private set;
        }

        protected GraphicsDevice GraphicsDevice
        {
            get { return _graphicsDevice; }
        }

        protected ContentManager Content
        {
            get { return _content; }
        }

        #endregion

        #region Initialization

        protected XnaGame(GraphicsDevice graphicsDevice, IContentManagerProvider contentManagerProvider)
        {
            try
            {
                _graphicsDevice = graphicsDevice;
                _content = contentManagerProvider.GetContentManager(graphicsDevice);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }

        }

        protected virtual void Initialize() { }

        protected virtual void LoadContent() { }

        #endregion

        #region Destruction

        public void Dispose()
        {
            OnDispose(true);
            GC.SuppressFinalize(this);
        }

        ~XnaGame()
        {
            OnDispose(false);
        }

        protected virtual void OnDispose(bool disposing)
        {
            if (disposing)
            {
                _content.Dispose();
            }
        }

        #endregion

        #region Running

        public void Run()
        {
            if (Running)
            {
                throw new InvalidOperationException("The game is already running");
            }

            Running = true;

            Initialize();
            LoadContent();
        }

        public void Tick()
        {
            if (!Running)
            {
                throw new InvalidOperationException("Game is not running");
            }

            BeforeTick();

            FrameworkDispatcher.Update();
            Update();

            _graphicsDevice.Clear(Color.Black);
            Draw();
            Present();
        }

        #endregion

        #region Update

        protected virtual void BeforeTick() { }

        protected virtual void Update() { }

        #endregion

        #region Draw

        protected virtual void Draw() { }

        protected abstract void Present();

        #endregion
    }
}
